//*******************************************引入头文件*********************************************
#include <stdio.h>   //使用了标准库函数
#include <stdlib.h>  //使用了动态内存分配函数
#include <windows.h>

//******************************************自定义符号常量*******************************************

#define OVERFLOW -2         //内存溢出错误常量
#define OK 1                //表示操作正确的常量
#define ERROR 0             //表示操作错误的常量

//******************************************自定义数据类型********************************************

typedef int Status;       //用typedef给int起个别名，也便于程序的维护
typedef int ElemType;   //用typedef给float起个别名，也便于程序的维护

typedef struct LNode {    //用C语言描述线性单链表的结构，声明结构体的同时声明一个结构体指针
    ElemType data;            //数据域
    struct LNode *next;       //指针域
} LNode, *LinkList;

//******************************************线性表的主要操作******************************************

//1.-------------------------------------线性单链表的初始化操作---------------------------------------
/*
	函数：MallocList_L
	参数：LinkList &L 带回创建的节点
	返回值：状态码，OK表示操作成功
	作用：申请一个节点的内存空间
*/
Status MallocList_L(LinkList *L) {
    //为线性表L开辟内存空间，只申请一个结点的内存空间
    *L = (LNode *) malloc(sizeof(LNode));
    if (! *L) {  //if(!L) <=> if(L == NULL)
        printf("申请内存失败！\n");
        exit(OVERFLOW);  //退出程序，并提示用户内存分配失败的原因是内存泄露
    }
    //操作成功
    return OK;
}

/*
	函数：InitList_L
	参数：LinkList &L 单链表的头指针
	      int n 线性表元素的个数
	返回值：状态码，OK表示操作成功
	作用：构造一个线性表并将其初始化
*/
Status InitList_L(LinkList *L, int n) {
    //先构造一个空的单链表，完成头结点的创建
    MallocList_L(L);
    //将头结点的指针域设置为NULL
    (*L)->next = NULL;
    //头结点数据域记录了单链表的长度，由于初始化了n个元素，所以赋值n
    (*L)->data = n;

    LinkList tail = *L;
    //2.使用尾插法创建带头结点的单链线性表L，按照正常位序输入元素
    for (int i = 0; i < n; i++) {
        //生成一个新结点，使p指向此结点
        LNode* p = NULL;
        MallocList_L(&p);
        //从键盘接收元素值，并存入p指向结点的数据域
        p->data = i;
        //将新申请的结点的指针域设为NULL，因为p结点要作为新的表尾结点使用，所以后面没有后继
        p->next = NULL;
        //将p节点链接到当前表尾元素的后面，成为新的表尾结点
        tail->next = p;
        //p成为了新的表尾结点，修改tail使其指向p
        tail = p;
    }
    //操作成功
    return OK;
}

//**********************************************主函数********************************************
int main(int argc, char *argv[]) {
    system("chcp 65001 > nul");

    printf("->初始化单链表La\n");
    // 这个是头结点
    LinkList La = NULL;
    InitList_L(&La, 5);
   for(int a=0;a<5;a++){
       printf("%d\n",La->data);
       La = La->next;
   }
    return 0;
}